/*

  xmunipack - file properties dialog

  Copyright © 2009-2011 F.Hroch (hroch@physics.muni.cz)

  This file is part of Munipack.

  Munipack is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.
  
  Munipack is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  
  You should have received a copy of the GNU General Public License
  along with Munipack.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "xmunipack.h"
#include <wx/wx.h>
#include <wx/propdlg.h>
#include <wx/generic/propdlg.h>
#include <vector>

using namespace std;


BEGIN_EVENT_TABLE(MuniThumbCanvas, wxWindow)
  EVT_PAINT(MuniThumbCanvas::OnPaint)
END_EVENT_TABLE()


MuniFileProperties::MuniFileProperties(wxWindow *w, const FitsMeta& fm,
				       const MuniConfig *config):
wxDialog(w,wxID_ANY,"Properties"),meta(fm)
{
  SetIcon(config->munipack_icon);

  wxFont bf(*wxNORMAL_FONT);
  bf.SetWeight(wxFONTWEIGHT_BOLD);

  wxString a;

  wxArrayString flabels;
  flabels.Add("Name:");
  flabels.Add("Format:");
  flabels.Add("Type:");
  flabels.Add("Hdu(s):");
  flabels.Add("Bytes:");
  flabels.Add("Access:");
  flabels.Add("Modified:");
  flabels.Add("Location:");

  wxArrayString fvals;
  // name
  fvals.Add(meta.GetFullName());

  // format
  fvals.Add("FITS");

  // type
  fvals.Add(meta.Type_str());

  // HDUs
  a.Printf("%d",(int) meta.HduCount());
  fvals.Add(a);

  // bytes
  fvals.Add(meta.GetHumanReadableSize());

  // access
  wxFileName fn(meta.GetFullPath());
  if( fn.IsFileReadable() && fn.IsFileWritable() )
    fvals.Add("Read - Write");
  else if( fn.IsFileReadable() && ! fn.IsFileWritable() )
    fvals.Add("Read only");
  else if( ! fn.IsFileReadable() &&  fn.IsFileWritable() )
    fvals.Add("Write only");
  else
    fvals.Add(wxEmptyString);

  // mtime
  fvals.Add(meta.Mtime());

  // location
  fvals.Add(meta.GetPath());

  wxNotebook *book = new wxNotebook(this,wxID_ANY);

  wxPanel* gpanel = new wxPanel(book);

  wxBoxSizer *gtop = new wxBoxSizer(wxHORIZONTAL);
  wxBoxSizer *gleft = new wxBoxSizer(wxVERTICAL);
  MuniThumbCanvas *th = new MuniThumbCanvas(gpanel,meta.GetIcon());
  gleft->Add(th,wxSizerFlags().Center());
  gtop->Add(gleft,wxSizerFlags().Border(wxALL));

  wxSizerFlags flags; flags.Align(wxALIGN_BOTTOM);
  wxSizerFlags lflags; flags.Align(wxALIGN_BOTTOM).Border(wxRIGHT);

  wxFlexGridSizer *gright = new wxFlexGridSizer(2);

  // create the table
  for(size_t i = 0; i < flabels.GetCount(); i++) {
    
    wxStaticText *l = new wxStaticText(gpanel, wxID_ANY, flabels.Item(i));
    l->SetFont(bf);
    gright->Add(l,wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL).Border(wxRIGHT));
    wxStaticText *x = new wxStaticText(gpanel, wxID_ANY, fvals.Item(i));
    gright->Add(x,wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL).Expand());

  }

  gtop->Add(gright,wxSizerFlags().Border(wxALL));

  gpanel->SetSizer(gtop);

  book->AddPage(gpanel,"File");

  for(size_t k = 0; k < meta.HduCount(); k++ ) {

    FitsMetaHdu hdu = meta.Hdu(k);

    wxArrayString hlabels, hvals;
    wxString title("Component");

    // extname
    a = hdu.GetKey("EXTNAME");
    if( ! a.IsEmpty() ) {
      hlabels.Add("Extname:");
      hvals.Add(a);
    }

    // obj
    hlabels.Add("Object:");
    hvals.Add(hdu.GetKey(config->fits_object));

    // obs
    hlabels.Add("Observer:");
    hvals.Add(hdu.GetKey(config->fits_observer));

    if( hdu.Type() == HDU_IMAGE ) {

      title = "Image";

      // axes
      hlabels.Add("Axes:");
      a.Printf("%d",(int) hdu.Naxis());
      hvals.Add(a);

      switch(hdu.SubType()) {

      case HDU_IMAGE_LINE: 
	hlabels.Add("Length:");
	a.Printf("%d pix",(int) hdu.Width());
	hvals.Add(a);
	break;

      case HDU_IMAGE_FRAME:
	hlabels.Add("Width:");
	hlabels.Add("Height:");
	a.Printf("%d pix",(int) hdu.Width());
	hvals.Add(a);
	a.Printf("%d pix",(int) hdu.Height());
	hvals.Add(a);
	break;

      case HDU_IMAGE_COLOR:
	hlabels.Add("Bands:");
	hlabels.Add("Width:");
	hlabels.Add("Height:");
	a.Printf(wxT("%d"),(int) hdu.Naxes(2));
	hvals.Add(a);
	a.Printf(wxT("%d pix"),(int) hdu.Width());
	hvals.Add(a);
	a.Printf(wxT("%d pix"),(int) hdu.Height());
	hvals.Add(a);
	break;

      case HDU_IMAGE_CUBE:
	hlabels.Add("Width:");
	hlabels.Add("Height:");
	hlabels.Add("Depth:");
	a.Printf(wxT("%d pix"),(int) hdu.Width());
	hvals.Add(a);
	a.Printf(wxT("%d pix"),(int) hdu.Height());
	hvals.Add(a);
	a.Printf(wxT("%d pix"),(int) hdu.Naxes(2));
	hvals.Add(a);
	break;
      }
    }
    else if( hdu.Type() == HDU_TABLE ) {

      title = "Table";

      hlabels.Add("Rows:");
      hlabels.Add("Columns:");
      a.Printf("%d",(int) hdu.Nrows());
      hvals.Add(a);
      a.Printf("%d",(int) hdu.Ncols());
      hvals.Add(a);
    }
    else if( hdu.Type() == HDU_HEAD ) {

      title = "Head";

    }

    // date & time
    FitsTime t(hdu.GetKey(config->fits_dateobs));
    hlabels.Add("Date:");
    hlabels.Add("Time:");
    hvals.Add(t.Date());
    hvals.Add(t.Time());

    // filter
    hlabels.Add("Band:");
    hvals.Add(hdu.GetKey(config->fits_filter));

    // exp
    hlabels.Add("Exposure:");
    a = hdu.Exposure_str(config->fits_exposure);
    if( ! a.IsEmpty() )
       a = a + " sec";
    hvals.Add(a);

    // type
    hlabels.Add("Type:");
    hvals.Add(hdu.Type_str() + " (" + hdu.SubType_str() + ")");

    // range
    hlabels.Add("Range:");
    hvals.Add(hdu.Bitpix_str());


    wxPanel *panel = new wxPanel(book);
    
    wxBoxSizer *top = new wxBoxSizer(wxHORIZONTAL);
    wxBoxSizer *left = new wxBoxSizer(wxVERTICAL);

    MuniThumbCanvas *tb = new MuniThumbCanvas(panel,hdu.GetIcon());
    left->Add(tb,wxSizerFlags().Center());
    top->Add(left,wxSizerFlags().Border(wxALL));

    wxFlexGridSizer *right = new wxFlexGridSizer(2);

    // create the table
    for(size_t i = 0; i < hlabels.GetCount(); i++) {
    
      wxStaticText *l = new wxStaticText(panel, wxID_ANY, hlabels.Item(i));
      l->SetFont(bf);
      right->Add(l,wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL).Border(wxRIGHT));
      wxStaticText *x = new wxStaticText(panel, wxID_ANY, hvals.Item(i));
      right->Add(x,wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL).Expand());
 
    }

    top->Add(right,wxSizerFlags().Border(wxALL));

    panel->SetSizer(top);

    if( meta.HduCount() == 1 )
      a = "Image";
    else {
      a = hdu.GetKey("EXTNAME");
      if( a.IsEmpty() )
	a.Printf(title+" %d",(int) k);
    }
    book->AddPage(panel,a);

  }

  wxBoxSizer *topsizer = new wxBoxSizer(wxHORIZONTAL);
  topsizer->Add(book,wxSizerFlags(1).Expand().Border());
  SetSizerAndFit(topsizer);
}


// ------   MuniThumbCanvas


MuniThumbCanvas::MuniThumbCanvas(wxWindow *w, const wxBitmap& b):
  wxWindow(w,wxID_ANY,wxDefaultPosition,wxSize(b.GetWidth(),b.GetHeight())),
  icon(b)
{
  SetBackgroundStyle(wxBG_STYLE_CUSTOM);
}

void MuniThumbCanvas::OnPaint(wxPaintEvent& WXUNUSED(event))
{
  DrawIcon();
}

void MuniThumbCanvas::SetIcon(const wxBitmap& i)
{
  icon = i;
  DrawIcon();
}

void MuniThumbCanvas::SetIcon(const wxImage& i)
{
  SetIcon(wxBitmap(i));
}

void MuniThumbCanvas::DrawIcon()
{
  if( icon.IsOk() ) {
    wxSize s = GetSize();
    int xoff = (s.GetWidth() - icon.GetWidth())/2;
    int yoff = (s.GetHeight() - icon.GetHeight())/2;
    wxPaintDC dc(this);
    dc.DrawBitmap(icon,xoff,yoff,true);
  }
}



// ----  MuniDirProp


MuniDirProperties::MuniDirProperties(wxWindow *w, const MuniConfig *config,
				     const vector<FitsMeta>& flist):
  wxDialog(w,wxID_ANY,"Properties")
{
  SetIcon(config->munipack_icon);

  wxFont bf(*wxNORMAL_FONT);
  bf.SetWeight(wxFONTWEIGHT_BOLD);

  wxNotebook *book = new wxNotebook(this,wxID_ANY);

  wxPanel* gpanel = new wxPanel(book);

  wxBoxSizer *gtop = new wxBoxSizer(wxHORIZONTAL);
  wxBoxSizer *gleft = new wxBoxSizer(wxVERTICAL);

  MuniArtIcons icons(wxART_MESSAGE_BOX,wxSize(48,48));

  MuniThumbCanvas *th = new MuniThumbCanvas(gpanel,icons.Icon(wxART_FOLDER));
  gleft->Add(th,wxSizerFlags().Center());
  gtop->Add(gleft,wxSizerFlags().Border(wxALL));

  wxString a;
  a.Printf("%d",(int) flist.size());

  wxFlexGridSizer *gright = new wxFlexGridSizer(2);
  gright->AddGrowableCol(1);
  wxStaticText *l1 = new wxStaticText(gpanel, wxID_ANY, "Total Images:");
  l1->SetFont(bf);
  gright->Add(l1);
  gright->Add(new wxStaticText(gpanel, wxID_ANY,a));
  wxStaticText *l2 = new wxStaticText(gpanel, wxID_ANY, "Total bytes:");
  l2->SetFont(bf);
  gright->Add(l2);

  wxULongLong size = 0;
  for(vector<FitsMeta>::const_iterator i = flist.begin(); i != flist.end();++i){
    wxULongLong s = i->GetSize();
    if( s == wxInvalidSize ) {
      size = s;
      break;
    }
    size += s;
  }

  a = wxFileName::GetHumanReadableSize(size);
  gright->Add(new wxStaticText(gpanel, wxID_ANY,a));
  gtop->Add(gright,wxSizerFlags().Center().Border(wxALL));

  gpanel->SetSizer(gtop);
  gtop->Fit(gpanel);

  book->AddPage(gpanel,"General");

  wxBoxSizer *topsizer = new wxBoxSizer(wxHORIZONTAL);
  topsizer->Add(book,wxSizerFlags(1).Expand());
  SetSizerAndFit(topsizer); 
}

